package com.woniu113.junk.gateway.filter;

import cn.hutool.core.text.AntPathMatcher;

import com.woniu113.junk.gateway.config.ResourceProperties;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

import javax.annotation.Resource;
import java.util.List;

/**
 * 认证拦截器(全局)
 * 实现GlobalFilter全局拦截器,重写filter方法
 *
 * ServerWebExchange exchange:请求响应对象保存在其中,可以从中获取请求响应的数据
 * GatewayFilterChain chain:用于控制拦截器通过(return chain.filter(exchange)表示通过)
 *
 * DataBuffer:缓存
 * exchange.getResponse().bufferFactory():得到dataBuffer创建工厂
 * exchange.getResponse().bufferFactory().wrap():创建一个dataBuffer,warp中是设置响应内容
 */
@Order(1)
@Component //放入容器
public class AuthenticationFilter implements GlobalFilter {

    @Resource
    private ResourceProperties rp;//基础的配置文件

    /**
     * spring中格式匹配的工具类
     */
     private AntPathMatcher apm=new AntPathMatcher();

    /**
     *检查资源是否在某个集合里面
     */
    private Boolean isUrl(String url, List<String> urls){
        if (urls !=null && urls.size()>0){
            for (String ur : urls) {
                if (apm.match(ur,url)){//相等说明集合中存在这个资源,返回true（注意匹配的方式）
                    return true;
                }
            }
        }
        return false;//没有匹配到返回false
    }


    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        System.out.println("=======认证123====");
//        if (new Random().nextInt(10)>4){
//            throw new AuthenticationException("认证失败",401);
//        }

//        List<String> junkToken = exchange.getRequest().getHeaders().get("junk-token");
//        System.out.println("junkToken = " + junkToken);


        //1.获取到用户访问的资源是什么
        String url = exchange.getRequest().getPath().toString();//获取请求的资源名称(如:/movie/v2/api-docs)
        //2.匹配是否是公共资源放行的接口
        if (isUrl(url,rp.getBathUrls())){//如果传入的路径匹配上了公共资源,全部放行
            return chain.filter(exchange);
        }
        //3.公共资源没有匹配上,匹配下一个(此时需要检测这个url是用户端的还是管理员端的)
        //4.判定url是哪一个模块的
        if (url.endsWith(".api")){//如果是以.api结尾的说明是管理端的接口
            //管理端的接口就要匹配管理端
            if (isUrl(url,rp.getAdminUrls())){
                return chain.filter(exchange);//匹配上了,放行
            }
            //管理端解析
        }else {//否则就是用户端的接口
            //用户端的接口就要匹配用户端
            if (isUrl(url,rp.getUserUrls())){
                return chain.filter(exchange);//匹配上了,放行
            }
            //用户端解析
        }

        //表示通过
        return chain.filter(exchange);
    }


}
/**
 * 公共放行的
 * 用户端放行的
 * 管理端放行的
 * (配置到ResourceProperties.java)
 */
